
#include <cmath>
#include "ILibBase.h"

using namespace BWE;

ILibrary* ILibBase::Instance()
{
	static ILibrary library("cmath");

	if (library.empty())
	{
		library.registFunction("real time()", time);

		library.registFunction("byte min(byte, byte)", min_byte);
		library.registFunction("char min(char, char)", min_char);
		library.registFunction("int min(int, int)", min_int);
		library.registFunction("short min(short, short)", min_short);
		library.registFunction("long min(long, long)", min_long);
		library.registFunction("real min(real, real)", min_real);
		library.registFunction("float min(float, float)", min_float);
		library.registFunction("double min(double, double)", min_double);

		library.registFunction("byte max(byte, byte)", max_byte);
		library.registFunction("char max(char, char)", max_char);
		library.registFunction("int max(int, int)", max_int);
		library.registFunction("short max(short, short)", max_short);
		library.registFunction("long max(long, long)", max_long);
		library.registFunction("real max(real, real)", max_real);
		library.registFunction("float max(float, float)", max_float);
		library.registFunction("double max(double, double)", max_double);

		library.registFunction("byte swap(byte, byte)", swap_byte);
		library.registFunction("char swap(char, char)", swap_char);
		library.registFunction("int swap(int, int)", swap_int);
		library.registFunction("short swap(short, short)", swap_short);
		library.registFunction("long swap(long, long)", swap_long);
		library.registFunction("real swap(real, real)", swap_real);
		library.registFunction("float swap(float, float)", swap_float);
		library.registFunction("double swap(double, double)", swap_double);

		library.registFunction("real RTD(int)", RTD_int);
		library.registFunction("real RTD(real)", RTD_real);
		library.registFunction("float RTD(float)", RTD_float);
		library.registFunction("double RTD(double)", RTD_double);

		library.registFunction("real DTR(int)", DTR_int);
		library.registFunction("real DTR(real)", DTR_real);
		library.registFunction("float DTR(float)", DTR_float);
		library.registFunction("double DTR(double)", DTR_double);

		library.registFunction("bool Zero(int)", Zero_int);
		library.registFunction("bool Zero(real)", Zero_real);
		library.registFunction("bool Zero(float)", Zero_float);
		library.registFunction("bool Zero(double)", Zero_double);

		library.registFunction("bool NonZero(int)", NonZero_int);
		library.registFunction("bool NonZero(real)", NonZero_real);
		library.registFunction("bool NonZero(float)", NonZero_float);
		library.registFunction("bool NonZero(double)", NonZero_double);

		library.registFunction("bool Equal(real,real)", Equal_real);
		library.registFunction("bool Equal(float,float)", Equal_float);
		library.registFunction("bool Equal(double,double)", Equal_double);

		library.registFunction("string ByteToHex(byte)", ByteToHex);
		library.registFunction("string ShortToHex(ushort)", ShortToHex);
		library.registFunction("string UintToHex(uint)", UintToHex);
		library.registFunction("string UlongToHex(ulong)", UlongToHex);

		library.registFunction("string HexToByte(byte)", HexToByte);
		library.registFunction("string HexToShort(ushort)", HexToShort);
		library.registFunction("string HexToUint(uint)", HexToUint);
		library.registFunction("string HexToUlong(ulong)", HexToUlong);

		library.registFunction(" ", Lerp);

		library.registVariant("const double", "PId", PId);
		library.registVariant("const double", "PI2d", PI2d);

		library.registVariant("const float", "PIf", PIf);
		library.registVariant("const float", "PI2f", PI2f);

#ifdef REAL_IS_DOUBLE
		library.registVariant("const real", "PI", PI);
		library.registVariant("const real", "PI2", PI2);
		library.registVariant("const real", "REAL_EPSILON", REAL_EPSILON);
		library.registVariant("const real", "REAL_MAX", REAL_MAX);
		library.registVariant("const real", "REAL_LARGE", REAL_LARGE);
#else
		library.registVariant("const real", "PI", PI);
		library.registVariant("const real", "PI2", PI2);
		library.registVariant("const real", "REAL_EPSILON", REAL_EPSILON);
		library.registVariant("const real", "REAL_MAX", REAL_MAX);
		library.registVariant("const real", "REAL_LARGE", REAL_LARGE);
#endif

		library.registVariant("const double", "DBL_EPSILON", DBL_EPSILON);
		library.registVariant("const float", "FLT_EPSILON", FLT_EPSILON);
	}

	return &library;
}

void ILibBase::time(int argc, BValue* argv)
{
	argv[0] = bTime();
}

void ILibBase::min_byte(int argc, BValue* argv)
{
	BByte b1 = argv[1];
	BByte b2 = argv[2];
	argv[0] = bMin(b1, b2);
}
void ILibBase::min_char(int argc, BValue* argv)
{
	char c1 = argv[1];
	char c2 = argv[2];
	argv[0] = bMin(c1, c2);
}
void ILibBase::min_short(int argc, BValue* argv)
{
	BShort s1 = argv[1];
	BShort s2 = argv[2];
	argv[0] = bMin(s1, s2);
}
void ILibBase::min_int(int argc, BValue* argv)
{
	BInt i1 = argv[1];
	BInt i2 = argv[2];
	argv[0] = bMin(i1, i2);
}
void ILibBase::min_long(int argc, BValue* argv)
{
	BLong l1 = argv[1];
	BLong l2 = argv[2];
	argv[0] = bMin(l1, l2);
}
void ILibBase::min_real(int argc, BValue* argv)
{
	BReal r1 = argv[1];
	BReal r2 = argv[2];
	argv[0] = bMin(r1, r2);
}
void ILibBase::min_float(int argc, BValue* argv)
{
	float f1 = argv[1];
	float f2 = argv[2];
	argv[0] = bMin(f1, f2);
}
void ILibBase::min_double(int argc, BValue* argv)
{
	double d1 = argv[1];
	double d2 = argv[2];
	argv[0] = bMin(d1, d2);
}

void ILibBase::max_byte(int argc, BValue* argv)
{
	BByte b1 = argv[1];
	BByte b2 = argv[2];
	argv[0] = bMax(b1, b2);
}
void ILibBase::max_char(int argc, BValue* argv)
{
	char c1 = argv[1];
	char c2 = argv[2];
	argv[0] = bMax(c1, c2);
}
void ILibBase::max_short(int argc, BValue* argv)
{
	BShort s1 = argv[1];
	BShort s2 = argv[2];
	argv[0] = bMax(s1, s2);
}
void ILibBase::max_int(int argc, BValue* argv)
{
	BInt i1 = argv[1];
	BInt i2 = argv[2];
	argv[0] = bMax(i1, i2);
}
void ILibBase::max_long(int argc, BValue* argv)
{
	BLong l1 = argv[1];
	BLong l2 = argv[2];
	argv[0] = bMax(l1, l2);
}
void ILibBase::max_real(int argc, BValue* argv)
{
	BReal r1 = argv[1];
	BReal r2 = argv[2];
	argv[0] = bMax(r1, r2);
}
void ILibBase::max_float(int argc, BValue* argv)
{
	float f1 = argv[1];
	float f2 = argv[2];
	argv[0] = bMax(f1, f2);
}
void ILibBase::max_double(int argc, BValue* argv)
{
	double d1 = argv[1];
	double d2 = argv[2];
	argv[0] = bMax(d1, d2);
}

void ILibBase::swap_byte(int argc, BValue* argv)
{
	BByte& b1 = argv[1];
	BByte& b2 = argv[2];
	bSwap(b1, b2);
}
void ILibBase::swap_char(int argc, BValue* argv)
{
	char& c1 = argv[1];
	char& c2 = argv[2];
	bSwap(c1, c2);
}
void ILibBase::swap_short(int argc, BValue* argv)
{
	BShort& s1 = argv[1];
	BShort& s2 = argv[2];
	bSwap(s1, s2);
}
void ILibBase::swap_int(int argc, BValue* argv)
{
	BInt& i1 = argv[1];
	BInt& i2 = argv[2];
	bSwap(i1, i2);
}
void ILibBase::swap_long(int argc, BValue* argv)
{
	BLong& l1 = argv[1];
	BLong& l2 = argv[2];
	bSwap(l1, l2);
}
void ILibBase::swap_real(int argc, BValue* argv)
{
	BReal& r1 = argv[1];
	BReal& r2 = argv[2];
	bSwap(r1, r2);
}
void ILibBase::swap_float(int argc, BValue* argv)
{
	float& f1 = argv[1];
	float& f2 = argv[2];
	bSwap(f1, f2);
}
void ILibBase::swap_double(int argc, BValue* argv)
{
	double& d1 = argv[1];
	double& d2 = argv[2];
	bSwap(d1, d2);
}

void ILibBase::RTD_int(int argc, BValue* argv)
{
	int i = argv[1];
	argv[0] = bRTD((BReal)i);
}
void ILibBase::RTD_real(int argc, BValue* argv)
{
	BReal r = argv[1];
	argv[0] = bRTD(r);
}
void ILibBase::RTD_float(int argc, BValue* argv)
{
	float f = argv[1];
	argv[0] = bRTD(f);
}
void ILibBase::RTD_double(int argc, BValue* argv)
{
	double d = argv[1];
	argv[0] = bRTD(d);
}

void ILibBase::DTR_int(int argc, BValue* argv)
{
	int i = argv[1];
	argv[0] = bDTR((BReal)i);
}
void ILibBase::DTR_real(int argc, BValue* argv)
{
	BReal r = argv[1];
	argv[0] = bDTR(r);
}
void ILibBase::DTR_float(int argc, BValue* argv)
{
	float f = argv[1];
	argv[0] = bDTR(f);
}
void ILibBase::DTR_double(int argc, BValue* argv)
{
	double d = argv[1];
	argv[0] = bDTR(d);
}

void ILibBase::Zero_int(int argc, BValue* argv)
{
	BReal r = argv[1];
	argv[0] = bZero(r);
}
void ILibBase::Zero_real(int argc, BValue* argv)
{
	BReal r = argv[1];
	argv[0] = bZero(r);
}
void ILibBase::Zero_float(int argc, BValue* argv)
{
	float f = argv[1];
	argv[0] = bZero(f);
}
void ILibBase::Zero_double(int argc, BValue* argv)
{
	double d = argv[1];
	argv[0] = bZero(d);
}

void ILibBase::NonZero_int(int argc, BValue* argv)
{
	BReal r = argv[1];
	argv[0] = bNonZero(r);
}
void ILibBase::NonZero_real(int argc, BValue* argv)
{
	BReal r = argv[1];
	argv[0] = bNonZero(r);
}
void ILibBase::NonZero_float(int argc, BValue* argv)
{
	float f = argv[1];
	argv[0] = bNonZero(f);
}
void ILibBase::NonZero_double(int argc, BValue* argv)
{
	double d = argv[1];
	argv[0] = bNonZero(d);
}

void ILibBase::Equal_real(int argc, BValue* argv)
{
	BReal r1 = argv[1];
	BReal r2 = argv[2];
	argv[0] = bEqual(r1, r2);
}
void ILibBase::Equal_float(int argc, BValue* argv)
{
	float f1 = argv[1];
	float f2 = argv[2];
	argv[0] = bEqual(f1, f2);
}
void ILibBase::Equal_double(int argc, BValue* argv)
{
	double d1 = argv[1];
	double d2 = argv[2];
	argv[0] = bEqual(d1, d2);
}

void ILibBase::ByteToHex(int argc, BValue* argv)
{
	BByte value = argv[1];
	char hexs[4];
	bByteToHex(hexs, value);
	argv[0] = new BString(hexs);
}
void ILibBase::ShortToHex(int argc, BValue* argv)
{
	BUShort value = argv[1];
	char hexs[8];
	bShortToHex(hexs, value);
	argv[0] = new BString(hexs);
}
void ILibBase::UintToHex(int argc, BValue* argv)
{
	BUInt value = argv[1];
	char hexs[12];
	bIntToHex(hexs, value);
	argv[0] = new BString(hexs);
}
void ILibBase::UlongToHex(int argc, BValue* argv)
{
	BULong value = argv[1];
	char hexs[20];
	bLongToHex(hexs, value);
	argv[0] = new BString(hexs);
}

void ILibBase::HexToByte(int argc, BValue* argv)
{

}
void ILibBase::HexToShort(int argc, BValue* argv)
{

}
void ILibBase::HexToUint(int argc, BValue* argv)
{

}
void ILibBase::HexToUlong(int argc, BValue* argv)
{

}

void ILibBase::Lerp(int argc, BValue* argv)
{

}
